import * as fs                                                from 'fs';
import { app, contextBridge, Menu, nativeImage, shell, Tray } from 'electron';
import { exec } from 'child_process';
import * as remote from '@electron/remote';
import yaml from 'js-yaml';
import { Database, SchemaTableList, Table } from 'src/models/Orm';
import * as Path from 'path';
import { Connection, createPool, FieldInfo, MysqlError } from 'mysql';

import path from 'path';
import { gen } from 'src/api/ConfigApi';
let tray;
const iconv = require('iconv-lite');
const template = require('art-template');
let clearConnectionTimer: string | number | NodeJS.Timeout | null | undefined =
  null;
contextBridge.exposeInMainWorld('ipcCom', {
  Tray:()=>{
    const icon = nativeImage.createFromPath(
      path.join(__dirname, './icons/icon.png')
    );
    tray = new Tray(icon);
    const contextMenu = Menu.buildFromTemplate([
      // { role: 'appMenu' }

      {
        label: app.name,
        submenu: [
          { role: 'about' },
          { type: 'separator' },
          { role: 'services' },
          { type: 'separator' },
          { role: 'hide' },
          { role: 'hideOthers' },
          { role: 'unhide' },
          { type: 'separator' },
          { role: 'quit' },
          {
            label: 'asdas',
            click: async () => {
              await gen();
            },
          },
        ],
      },
    ]);

    tray.setContextMenu(contextMenu);
    tray.setToolTip('喵喵喵');
    tray.setTitle('呱呱呱');
  },
  minimize() {
    remote.getCurrentWindow().minimize();
  },
  toggleMaximize() {
    const win = remote.getCurrentWindow();
    if (win?.isMaximized()) {
      win?.unmaximize();
    } else {
      win?.maximize();
    }
  },
  isMaximized() {
    return remote.getCurrentWindow()?.isMaximized();
  },

  close() {
    remote.getCurrentWindow()?.close();
  },
  getDirname(): string {
    return __dirname;
  },
  getDocDirname(): string {
    return remote.app.getPath('documents');
  },
  selectFolder(title: string, currentPath: string): Promise<unknown> {
    return new Promise((resolve, reject) => {
      remote.dialog
        .showOpenDialog({
          title: title,
          defaultPath: currentPath,
          properties: ['openFile', 'openDirectory', 'showHiddenFiles'],
        })
        .then((result) => {
          resolve(result.filePaths[0]);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  openFolder(title: string, currentPath: string): Promise<unknown> {
    return new Promise(() => {
      remote.dialog
        .showOpenDialog({
          title: title,
          properties: ['openFile', 'multiSelections'],
          defaultPath: currentPath,
        })
        .then(() => {
          shell.beep();
        });
    });
  },
  selectFile(title: string): Promise<unknown> {
    return new Promise((resolve, reject) => {
      remote.dialog
        .showOpenDialog({
          title: title,
          properties: ['openFile'],
        })
        .then((result) => {
          resolve(result.filePaths[0]);
        })
        .catch((err) => {
          reject(err);
        });
    });
  },
  getRenderTemplate(path: string, data: object): Promise<string> {
    return new Promise((resolve) => {
      fs.existsSync(path)
        ? resolve(template.render(fs.readFileSync(path, 'utf8'), data))
        : resolve('文件不存在');
    });
  },
  pathJoin(path: string[]): string {
    return Path.join(...path);
  },
  explorerFolder(path: string): void {
    exec(`explorer ${path}`, (error) => {
      if (error) {
        console.error(`执行命令时出错：${error}`);
        return;
      }

      // console.log('成功打开资源管理器文件夹');
    });
  },
  execute(data: string): Promise<string> {
    return new Promise((resolve) => {
      console.log(iconv.decode(cmd.runSync(data), 'cp936'));
      exec(data, { encoding: 'buffer' }, (error, stdout, stderr) => {
        if (error) {
          console.error(`执行命令时发生错误: ${error}`);
          return;
        }
        if (stdout) resolve(iconv.decode(stdout, 'cp936'));
        if (stderr) resolve(iconv.decode(stderr, 'cp936'));
      });
    });
  },
  renderTemplate(templatePath: string, data: object): Promise<string> {
    return new Promise((resolve) => {
      resolve(template.render(fs.readFileSync(templatePath, 'utf8'), data));
    });
  },
  renderTemplateContent(content: string, data: object): Promise<string> {
    return new Promise((resolve) => {
      resolve(template.render(content, data));
    });
  },
  templateGenerator(
    templatePath: string,
    outPath: string,
    data: object
  ): Promise<string> {
    return new Promise((resolve) => {
      // 模板文件是否存在
      if (fs.existsSync(templatePath)) {
        // 输出目录是否存在
        if (fs.existsSync(outPath)) {
          try {
            /*
             * 保存模板渲染的data到文件
             * @param {string} outPath 输出目录
             * @param {string} data 模板渲染 template.render(fs.readFileSync(templatePath, 'utf8'), data)
             * */
            fs.writeFileSync(
              outPath,
              template.render(fs.readFileSync(templatePath, 'utf8'), data)
            );
            resolve('文件保存成功！');
          } catch (error) {
            resolve('生成失败');
          }
        } else {
          // console.log('目录不存在');
          // 递归创建输出目录
          fs.mkdir(Path.dirname(outPath), { recursive: true }, (err) => {
            if (err) {
              resolve('目录创建失败');
            } else {
              try {
                /*
                 * 保存模板渲染的data到文件
                 * @param {string} outPath 输出目录
                 * @param {string} data 模板渲染 template.render(fs.readFileSync(templatePath, 'utf8'), data)
                 * */
                fs.writeFileSync(
                  outPath,
                  template.render(fs.readFileSync(templatePath, 'utf8'), data)
                );
                resolve('文件保存成功！');
              } catch (error) {
                resolve('文件保存错误：' + JSON.stringify(error));
              }
            }
          });
        }
      } else {
        resolve('模板文件不存在');
      }
    });
  },

  getTemplate(path: string): Promise<string> {
    return new Promise((resolve) => {
      resolve(fs.readFileSync(path, 'utf8'));
    });
  },
  extname(path: string): string {
    return Path.extname(path);
  },

  isFile(path: string): Promise<boolean> {
    return new Promise((resolve) => {
      fs.stat(path, (err, stats) => {
        if (err) {
          console.error(err);
          return;
        }
        if (stats.isFile()) {
          resolve(true);
        } else {
          resolve(false);
        }
      });
    });
  },
  getFilePathTree(path: string): Promise<string[]> {
    return new Promise((resolve) => {
      fs.readdir(path, (err, files) => {
        resolve(files);
      });
    });
  },
  getConnection(data: Database): Promise<SchemaTableList> {
    return new Promise((resolve) => {
      const pool = createPool({
        host: data.host, //'120.79.244.217',
        user: data.username, //'mall',
        password: data.password, //'NrGJeKxy2SMsK6sT',
        database: data.database, //'mall',
        port: data.port || 3306, //3306,
      });
      window.mysqlPool = pool;
      resolve(window.mysqlPool);
    });
  },
  SysConfig: {
    save(path: string, data: object): Promise<string> {
      return new Promise<string>((resolve, reject) => {
        try {
          fs.writeFileSync(path, yaml.dump(data));
          resolve('YAML文件已成功创建！');
        } catch (error) {
          reject('创建YAML文件时出错：' + JSON.stringify(error));
        }
      });
    },
    get(path: string, init: boolean): Promise<SysConfigParams> {
      return new Promise((resolve, reject) => {
        // 检查文件是否存在
        if (fs.existsSync(path)) {
          // 文件存在，返回文件内容
          resolve(yaml.load(fs.readFileSync(path, 'utf8')) as SysConfigParams);
        } else {
          if (init) {
            // 文件不存在，创建文件并返回默认内容
            try {
              // 将JavaScript对象转换为YAML格式的字符串
              // 将YAML字符串写入文件
              fs.writeFileSync(path, '');
            } catch (error) {}
            return yaml.load(fs.readFileSync(path, 'utf8')) as SysConfigParams;
          } else {
            reject('文件不存在');
          }
        }
      });
    },
  },
  getUniqueId: function (): string {
    const machineId = require('node-machine-id');
    // 获取机器的唯一标识符
    return machineId.machineIdSync();
  },
  notion: function (title: string, body: string, path: string): void {
    // 创建通知
    const notification: Electron.Notification = new remote.Notification({
      title: title,
      body: body,
      silent: true,
      timeoutType: 'never',
      icon: './public/logo.png',
      hasReply: true,
    });
    notification.addListener('click', () => {
      exec(`explorer ${path}`);
    });
    notification.show();
  },
  saveFileText(path: string, data: string): Promise<string> {
    return new Promise<string>((resolve, reject) => {
      if (fs.existsSync(path)) {
        try {
          fs.writeFileSync(path, data);
          resolve('文件保存成功！');
        } catch (error) {
          reject('文件保存错误：' + JSON.stringify(error));
        }
      } else {
        fs.mkdir(Path.dirname(path), { recursive: true }, (err) => {
          if (err) {
            reject(err);
          } else {
            try {
              fs.writeFileSync(path, data);
              resolve('文件保存成功！');
            } catch (error) {
              reject('文件保存错误：' + JSON.stringify(error));
            }
          }
        });
      }
    });
  },
  getFileDirname(src: string): string {
    return Path.dirname(src);
  },
  getFileText(path: string, init: boolean): Promise<string> {
    return new Promise((resolve, reject) => {
      if (fs.existsSync(path)) {
        // 文件存在，返回文件内容
        resolve(fs.readFileSync(path, 'utf8'));
      } else {
        if (init) {
          fs.mkdir(Path.dirname(path), { recursive: true }, (err) => {
            if (err) {
              reject(err);
            } else {
              try {
                fs.writeFileSync(path, '');
                resolve(fs.readFileSync(path, 'utf8'));
              } catch (error) {
                reject('文件保存错误：' + JSON.stringify(error));
              }
            }
          });
        } else {
          resolve('文件不存在');
        }
      }
    });
  },
  initDatabase(data: Database): Promise<string | null> {
    return new Promise((resolve) => {
      const dbPool = createPool({
        host: data.host, //'120.79.244.217',
        user: data.username, //'mall',
        password: data.password, //'NrGJeKxy2SMsK6sT',
        database: data.database, //'mall',
        port: data.port || 3306, //3306,
        connectTimeout: 60000,
        connectionLimit: 10,
      });
      window.mysqlPool = dbPool;
      resolve(dbPool);
    });
  },
  refreshDatabase(data: Database): Promise<string | null> {
    return new Promise((resolve) => {
      const dbPool = createPool(data);
      window.mysqlPool = dbPool;
      resolve(dbPool);
    });
  },
  refreshDatabaseOutTime(timeOut?: number): Promise<string | null> {
    return new Promise((resolve) => {
      if (clearConnectionTimer) clearTimeout(clearConnectionTimer);
      clearConnectionTimer = setTimeout(() => {
        const dbPool = window.mysqlPool;
        if (dbPool) dbPool.end();
      }, timeOut || 60000);
      resolve(null);
    });
  },
  stmtSql(sql: string): Promise<object | null> {
    return new Promise((resolve) => {
      // 查询操作
      window.mysqlPool.getConnection(
        (err: MysqlError, connection: Connection) => {
          if (err) {
            resolve(null);
            return;
          }
          connection.query(
            sql,
            (
              err: MysqlError,
              results: Table[] | null,
              fields: FieldInfo | null
            ) => {
              connection.release();
              if (err) {
                resolve(err);
                return;
              }
              resolve({ results, fields });
            }
          );
        }
      );
    });
  },
  tableMenu: (): Promise<string> => {
    return new Promise((resolve) => {
      const contextMenu = remote.Menu.buildFromTemplate([
        {
          label: '查询表',
          click: () => {
            resolve('query');
          },
        },
        {
          type: 'separator',
        },
        {
          label: '修改表',
          click: () => {
            resolve('edit');
          },
        },
        {
          type: 'separator',
        },
        {
          label: '复制名字',
          click: () => {
            resolve('copy');
          },
        },
      ]);
      contextMenu.popup({ window: remote.getCurrentWindow() });
    });
  },
  test: () => {
    alert(__dirname);
    alert(path.join(__dirname, './icons/icon.png'));
  },
  dbMenu: (): Promise<string> => {
    return new Promise((resolve) => {
      const contextMenu = remote.Menu.buildFromTemplate([
        {
          label: '添加表',
          click: () => {
            resolve('table');
          },
        },
        {
          type: 'separator',
        },
        {
          label: '添加视图',
          click: () => {
            resolve('view');
          },
        },
      ]);
      contextMenu.popup({ window: remote.getCurrentWindow() });
    });
  },
  fieldMenu: (): Promise<string> => {
    return new Promise((resolve) => {
      const contextMenu = remote.Menu.buildFromTemplate([
        {
          label: '修改字段',
          click: () => {
            resolve('add');
          },
        },
        {
          type: 'separator',
        },
        {
          label: '复制名字',
          click: () => {
            resolve('copy');
          },
        },
      ]);
      contextMenu.popup({ window: remote.getCurrentWindow() });
    });
  },
  clipboard: (textToCopy: string) => {
    remote.clipboard.writeText(textToCopy);
  },
});
